package com.sc.security.service.impl;

import com.google.common.collect.Lists;
import com.sc.security.common.CacheKeyConstants;
import com.sc.security.common.RequestHolder;
import com.sc.security.dao.SysAclMapper;
import com.sc.security.dao.SysRoleAclMapper;
import com.sc.security.dao.SysRoleUserMapper;
import com.sc.security.model.SysAcl;
import com.sc.security.service.CacheService;
import com.sc.security.service.SysCoreService;
import com.sc.security.utils.JsonMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class SysCoreServiceImpl implements SysCoreService{
    @Autowired
    private SysAclMapper aclMapper;
    @Autowired
    private SysRoleUserMapper roleUserMapper;
    @Autowired
    private SysRoleAclMapper roleAclMapper;
    @Autowired
    private CacheService cacheService;

    @Override
    public List<SysAcl> getCurrentUserAclList() {
        int userId = RequestHolder.getCurrentUser().getId();
        return getUserAclList(userId);
    }

    @Override
    public List<SysAcl> getRoleAclList(int roleId) {
       List<Integer> aclIdList =  roleAclMapper.getAclIdListByRoleIdList(Lists.newArrayList(roleId));
       if(CollectionUtils.isEmpty(aclIdList)){
           return Lists.newArrayList();
       }
       return aclMapper.getByIdList(aclIdList);
    }

    @Override
    public List<SysAcl> getUserAclList(int userId) {
        if(isSupperAdmin()){
            return aclMapper.getAll();
        }
        List<Integer> userRoleIdList = roleUserMapper.getRoleIdListByUserId(userId);
        if(CollectionUtils.isEmpty(userRoleIdList)){
            return Lists.newArrayList();
        }
        List<Integer> aclIdList = roleAclMapper.getAclIdListByRoleIdList(userRoleIdList);
        if(CollectionUtils.isEmpty(aclIdList)){
            return Lists.newArrayList();
        }
        return aclMapper.getByIdList(aclIdList);
    }

    @Override
    public boolean hasUrlAcl(String url) {
        if(isSupperAdmin()){
            return true;
        }
        List<SysAcl> userAclList = getCurrentUserAclListFromCache();


        Set<Integer> userAclSet = userAclList.stream().map(acl -> acl.getId()).collect(Collectors.toSet());
        List <SysAcl> aclList = aclMapper.getByUrl(url);
        if(CollectionUtils.isEmpty(aclList)){
            return true;
        }
        boolean hasValid = false;
        for(SysAcl acl:aclList){
            //判断一个用户是否具有权限
            if(acl==null||acl.getStatus()!=1){
               //无效
               continue;
            }
            hasValid=true;
            if(userAclSet.contains(acl.getId())){
                return true;
            }
        }
        if(!hasValid){
            return true;
        }
        return false;
    }

    private List<SysAcl> getCurrentUserAclListFromCache() {
        int userId = RequestHolder.getCurrentUser().getId();
        String cacheValue = cacheService.getFromCache(CacheKeyConstants.USER_ACLS,String.valueOf(userId));
        if(StringUtils.isBlank(cacheValue)){
            List<SysAcl> userAclList = getCurrentUserAclList();
            if(CollectionUtils.isNotEmpty(userAclList)){
                cacheService.saveCache(JsonMapper.obj2String(userAclList),600,CacheKeyConstants.USER_ACLS,String.valueOf(userId));
            }
            return userAclList;
        }
        return JsonMapper.string2Obj(cacheValue, new TypeReference<List<SysAcl>>() {
        });
    }

    private boolean isSupperAdmin(){
        return true;
    }
}
